import { useRef, useEffect, useState } from 'react';
import { KaTeXRenderer } from '../../core/renderer/KaTeXRenderer';
import type { FormulaFormatOptions } from '../../types';
import './FormulaPreview.css';

interface FormulaPreviewProps {
  latex: string;
  formatOptions: FormulaFormatOptions;
  showErrors?: boolean;
}

/**
 * 公式预览组件 - 实时渲染并显示LaTeX公式
 */
export const FormulaPreview: React.FC<FormulaPreviewProps> = ({
  latex,
  formatOptions,
  showErrors = true
}) => {
  const [renderedHtml, setRenderedHtml] = useState<string>('');
  const [error, setError] = useState<string | null>(null);
  const [isRendering, setIsRendering] = useState<boolean>(false);
  const previewRef = useRef<HTMLDivElement>(null);
  // 不需要创建实例，直接使用静态方法
  const renderTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  // 防抖处理渲染
  useEffect(() => {
    // 清除之前的超时
    if (renderTimeoutRef.current) {
      clearTimeout(renderTimeoutRef.current);
    }

    // 如果没有LaTeX内容，清空预览
    if (!latex || latex.trim() === '') {
      setRenderedHtml('');
      setError(null);
      setIsRendering(false);
      return;
    }

    // 设置渲染状态
    setIsRendering(true);
    setError(null);

    // 延迟渲染，实现防抖
    renderTimeoutRef.current = setTimeout(() => {
      try {
        // 使用KaTeX渲染器渲染公式
        const { html } = KaTeXRenderer.renderToHtml(latex, {
          displayMode: true,
          throwOnError: false,
          ...formatOptions
        });
        
        setRenderedHtml(html);
        setError(null);
      } catch (err) {
        // 捕获渲染错误
        setError(err instanceof Error ? err.message : '渲染公式时发生错误');
        setRenderedHtml('');
      } finally {
        setIsRendering(false);
      }
    }, 300); // 300ms防抖延迟

    // 组件卸载时清除
    return () => {
      if (renderTimeoutRef.current) {
        clearTimeout(renderTimeoutRef.current);
      }
    };
  }, [latex, formatOptions, showErrors]);

  // 监听容器大小变化，调整渲染
  useEffect(() => {
    const resizeObserver = new ResizeObserver(() => {
      // 容器大小变化时重新渲染，确保公式适应容器
      if (latex && latex.trim() !== '' && !error) {
        try {
          const { html } = KaTeXRenderer.renderToHtml(latex, {
            displayMode: true,
            throwOnError: false,
            ...formatOptions
          });
          setRenderedHtml(html);
        } catch (err) {
          // 忽略重新渲染时的错误
        }
      }
    });

    if (previewRef.current) {
      resizeObserver.observe(previewRef.current);
    }

    return () => {
      resizeObserver.disconnect();
    };
  }, [latex, formatOptions, error]);

  // 复制预览内容的功能
  const handleCopyPreview = () => {
    if (previewRef.current) {
      try {
        // 选择预览元素
        const selection = window.getSelection();
        const range = document.createRange();
        range.selectNodeContents(previewRef.current);
        selection?.removeAllRanges();
        selection?.addRange(range);
        
        // 执行复制
        document.execCommand('copy');
        
        // 清除选择
        selection?.removeAllRanges();
        
        // 这里可以添加复制成功的提示
        console.log('预览内容已复制到剪贴板');
      } catch (err) {
        console.error('复制预览内容失败:', err);
      }
    }
  };

  return (
    <div className="formula-preview-container">
      {/* 预览标题栏 */}
      <div className="preview-header">
        <h3 className="preview-title">实时预览</h3>
        {renderedHtml && (
          <button 
            className="copy-preview-button"
            onClick={handleCopyPreview}
            title="复制预览内容"
          >
            复制
          </button>
        )}
      </div>
      
      {/* 预览内容区域 */}
      <div className="preview-content">
        {isRendering ? (
          <div className="preview-loading">
            <div className="loading-spinner"></div>
            <span>渲染中...</span>
          </div>
        ) : error && showErrors ? (
          <div className="preview-error">
            <div className="error-icon">⚠️</div>
            <div className="error-message">
              <strong>渲染错误:</strong>
              <p>{error}</p>
            </div>
          </div>
        ) : latex.trim() === '' ? (
          <div className="preview-empty">
            <p>输入LaTeX公式以查看预览</p>
          </div>
        ) : (
          <div 
            ref={previewRef}
            className="preview-formula"
            dangerouslySetInnerHTML={{ __html: renderedHtml }}
          />
        )}
      </div>
      
      {/* 预览信息 */}
      {renderedHtml && (
        <div className="preview-info">
          <span className="formula-status">公式渲染成功</span>
        </div>
      )}
    </div>
  );
};

export default FormulaPreview;